<template>
  <el-dialog
    :title="lang.t('components.excel.title')"
    v-model="show"
    :width="610"
  >
    <slot></slot>
    <el-transfer
      v-model="value"
      :titles="[lang.t('components.excel.left'), lang.t('components.excel.right')]"
      :data="column"
    />
    <div v-if="progress.total" style="margin-top:30px">
      <el-progress 
        :status="progress.status" 
        :percentage="progress.length / progress.total * 100" 
        :show-text="false" 
      />
      <div style="text-align: center;padding-top: 20px; ">
        <el-link :type="progress.type" href="javascript:;">
          {{  lang.t('components.excel.' + progress.type, progress) }}
        </el-link>
      </div>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" :loading="loading" @click="onSave">{{ lang.t('components.excel.save') }}</el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script>
import { ref } from 'vue'
import app from '@/app'
import XLSX from 'xlsx'

export default {
  emits: ['load'],
  props: ['select'],
  setup(props, { emit }) {
    // 保存路径
    let path = ''

    // 已选择项
    const value = ref([])
    // 列
    const column = ref([])

    // 进度
    const progress = ref({
      length: 0,
      total: 0,
      status: '', 
      type: ''
    })

    // 对话框
    const show = ref(false)

    // 导出
    const loading = ref(false)

    // 整理可导出项
    const selectColumn = () => {
      column.value = []
      // 循环整理
      for (const key in props.select) {
        column.value.push({
          key,
          label: props.select[key].label
        })
      }
    }

    // 已选择项生成表头
    const selectHeader = () => {
      return value.value.map(key => {
        return props.select[key].label
      })
    }

    // 已选择项循环渲染
    const selectRender = data => {
      // 循环已选择项
      return value.value.map(key => {
        return props.select[key].render(data)
      })
    }
    
    // 开始导出
    const onSave = () => {
      // 加载事件
      emit('load')
    }

    // 打开
    const open = () => {
      // 判断是否正在导入
      if(loading.value) {
        return show.value = true
      }

      // 保存路径
      path = app.window.dialogSave({
        defaultPath: 'export' + app.time.file() + '.xlsx',
        filters: [{ 
          name: 'Excel', 
          extensions: ['xlsx'] 
        }]
      })

      if(path) {
        // 选择转为列
        selectColumn()
        // 显示窗口
        show.value = true
        // 数量清零
        progress.value.total = 0
        // 已选项没有
        value.value = []
      }
    }

    // 加载数据
    const load = async(func, footer) => {
      // 准备加载
      loading.value = true
      
      // 临时数据
      let temp = {}

      // 表格数据
      const table = []

      // 先执行方法
      do {
        // 传入加载方法闭包
        const [total, data] = await func(temp)

        // 合并数据
        data.forEach(item => {
          // 根据已选择项来处理数据
          table.push(selectRender(item))
        })

        // 加载进度
        progress.value = {
          length: table.length,
          total: total,
          status: '',
          type: 'primary'
        }
      } 
      // 再执行循环
      while (progress.value.length < progress.value.total);

      // 插入已选择项表头
      table.unshift(selectHeader())
      
      // 最后处理
      if(footer) {
        table.push(...footer(table))
      }

      // 创建表格工作薄
      const wb = XLSX.utils.book_new();
      const ws= XLSX.utils.aoa_to_sheet(table)
      XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
      
      // 保存成为文件
      XLSX.writeFileAsync(path, wb, res => {
        // 加载完成
        progress.value.status = res ? 'exception' : 'success'
        progress.value.type = res ? 'danger' : 'success'
        loading.value = false
        // 显示文件 
        app.window.fileShow(path)

        app.ui.notify({
          title: app.lang.t('components.excel.title'),
          type: res ? 'error' : 'success', 
          message: app.lang.t('components.excel.' + progress.value.type, progress.value),
          duration: 0,
          offset: 100,
        })
      })
    }

    return {
      lang: app.lang,
      column,
      value,
      progress,
      show,
      loading,
      onSave,
      open,
      load,
    }
  }
}
</script>